package com.uzai.console.service.useraccdetail.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.uzai.common.entity.User;
import com.uzai.common.entity.WechatUser;
import com.uzai.common.entity.WxpubUser;
import com.uzai.common.entity.WxworkUser;
import com.uzai.common.enums.*;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.msg.MsgDto;
import com.uzai.common.msg.NoticeMsgDto;
import com.uzai.common.result.ResponseCode;
import com.uzai.common.utils.Math;
import com.uzai.console.common.ResponseMsg;
import com.uzai.console.common.utils.DateUtil;
import com.uzai.console.common.utils.Tools;
import com.uzai.console.entity.*;
import com.uzai.console.mapper.*;
import com.uzai.console.service.cms.CmsParamReplaceService;
import com.uzai.console.service.device.DeviceService;
import com.uzai.console.service.rocketmq.NoticeMsgPushProducerService;
import com.uzai.console.service.user.UserService;
import com.uzai.console.service.useraccdetail.UserAccDetailService;
import com.uzai.console.vo.order.BaseOrderVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


/**
 * @author liuqi
 * @date 2021年09月01日 19:26
 */
@Service
@Slf4j
public class UserAccDetailServiceImpl implements UserAccDetailService {

    @Autowired
    private UserAccDetailMapper userAccDetailMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private ConfigPlanMapper configPlanMapper;
    @Autowired
    private SysPluginMapper sysPluginMapper;
    @Autowired
    private CmsParamReplaceService cmsParamReplaceService;
    @Autowired
    private NoticeMsgPushProducerService noticeMsgPushProducerService;
    @Autowired
    private WechatUserMapper wechatUserMapper;
    @Autowired
    private WxworkUserMapper wxworkUserMapper;

    @Autowired
    private WxpubUserMapper wxpubUserMapper;
    @Autowired
    private AppUserMapper appUserMapper;

    /**
     * 通过追回返利修改账户信息
     * @author liuqi
     * @date 2021/8/25 11:38
     * @return null
     */
   public void updateByRebateRefound(Long merId, String parentOrderNo, String childOrderNo, Long userId, String deviceType, Long deviceUniqueId,
                                     int reUserInte, double reUserBal, double reParentUserBal, double reSlParentUserBal, double reAgentBal, double reSlAgentBal, double rePartnerBal, int now, BaseOrderVo baseOrderVo){

       //tradeNo 设为空
       String tradeNo = null;
       //orderId = 运营商账号_父订单号_子订单号
       String orderId = merId + "_" + parentOrderNo + "_" + childOrderNo;

       UserAccDetail userAccDetail = userAccDetailMapper.selectByUserIdAndTypeAndOrderId(merId, AccDetailTypeEnum.REBATE_REFOUND.getValue(), orderId);
       //还未产生扣款明细则新增加，如果有了就跳过不新增
       if(userAccDetail == null){

           //查询用户信息
           User user = userService.findUserInfo(userId, deviceType, merId);
           if (user != null){
               //扣款用户返利
               updateBalance(reUserBal, reUserInte, now, user, AccDetailTypeEnum.REBATE_REFOUND.getValue(), orderId, 0l, deviceUniqueId, tradeNo);

               //上级返利
               User parentUser = userService.findUserInfo(user.getParentId(), user.getDeviceType(), merId);
               if(parentUser != null){
                   //扣款上级返利
                   updateBalance(reParentUserBal,0, now, parentUser, AccDetailTypeEnum.REBATE_REFOUND.getValue(), orderId, user.getId(), deviceUniqueId, tradeNo);

                   //上上级返利
                   User slParentUser = userService.findUserInfo(parentUser.getParentId(), user.getDeviceType(), merId);
                   if(slParentUser != null){
                       //扣款上上级返利
                       updateBalance(reSlParentUserBal,0, now, slParentUser, AccDetailTypeEnum.REBATE_REFOUND.getValue(), orderId, user.getId(), deviceUniqueId, tradeNo);
                   }
               }

               //代理人返利
               User reAgenter = userService.findUserInfo(user.getAgentId(), user.getDeviceType(), merId);
               if(reAgenter != null ){
                   //扣款代理人返利
                   updateBalance(reAgentBal,0, now, reAgenter, AccDetailTypeEnum.REBATE_REFOUND.getValue(), orderId, user.getId(), deviceUniqueId, tradeNo);

                   //上级代理人返利
                   User slAgenter = userService.findUserInfo(reAgenter.getAgentId(), user.getDeviceType(), merId);
                   if(slAgenter != null){
                       //扣款上级代理返利
                       updateBalance(reSlAgentBal,0, now, slAgenter, AccDetailTypeEnum.REBATE_REFOUND.getValue(), orderId, user.getId(), deviceUniqueId, tradeNo);
                   }
               }

               //合伙人返利
               User partner = userService.findUserInfo(user.getPartnerId(), user.getDeviceType(), merId);
               if(partner != null){
                   //扣款上级代理返利
                   updateBalance(rePartnerBal,0, now, partner, AccDetailTypeEnum.REBATE_REFOUND.getValue(), orderId, user.getId(), deviceUniqueId, tradeNo);
               }

               //发送淘宝订单追回返利回复消息
               sendMsgForRebateRefound(user, baseOrderVo);
           }
       }
   }

    /**
     * 修改会员账户余额
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param nowUser
     * @return null
     */
    public void updateBalance(double newBalance,int integral, int now, User nowUser,int awardType, String orderId, Long sourceId, Long deviceUniqueId, String tradeno) {
        User user = new User();
        user.setId(nowUser.getId());
        user.setMerId(nowUser.getMerId());
        user.setDeviceType(nowUser.getDeviceType());
        user.setUpdateTime(now);
        user.setVersion(nowUser.getVersion());
        user.setBalance(Math.sub(nowUser.getBalance(), newBalance));
        user.setIntegral(nowUser.getIntegral() - integral);
        int count = userService.updateBalance(user);
        if (count==0){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.NET_ERROR);
        }

        UserAccDetail dub = new UserAccDetail();
        dub.setId(IdWorker.getId());
        dub.setTradeno(tradeno);
        dub.setMerId(nowUser.getMerId());
        dub.setUserId(nowUser.getId());
        dub.setDeviceUniqueId(deviceUniqueId);
        dub.setDeviceType(nowUser.getDeviceType());
        dub.setChangeInte(0-integral); //扣除变动积分就是负数
        dub.setChangeBal(0-newBalance); //扣除变动金额就是负数
        dub.setNewInte(user.getIntegral());
        dub.setNewBal(user.getBalance());
        dub.setType(awardType);
        dub.setOrderId(orderId);
        dub.setSourceUserId(sourceId);
        dub.setCreateTime(now);
        dub.setUpdateTime(now);

        //插入用户账户明细记录
        int insert = userAccDetailMapper.insert(dub);
        if(insert!=1){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "增加账号明细失败");
        }

    }

    /**
     * 提现相关的修改账号余额
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param userTakeBal
     * @return null
     */
    @Transactional
    public void updateBalance(UserTakeBal userTakeBal){
        int now = DateUtil.getNowTime();
        //新余额
        double newBalance = 0.00d;
        //新积分
        int newIntegral = 0;
        //修改用户余额
        if (userTakeBal.getDeviceType().equals(DeviceTypeEnum.DT_PC_WECHAT.getKey())) { //个人微信用户
            WechatUser wechatUser = wechatUserMapper.selectById(userTakeBal.getUserId(), userTakeBal.getMerId());
            if (wechatUser == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该个人微信用户不存在");
            }

            //计算用户余额并修改
            Double oldBalance = wechatUser.getBalance();
            //修改余额
            newBalance = Math.add(oldBalance, userTakeBal.getTakeBal());
            newIntegral = wechatUser.getIntegral();
            wechatUser.setBalance(newBalance);
            wechatUser.setUpdateTime(now);
            int j = wechatUserMapper.updateBalance(wechatUser);
            if (j != 1) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.NET_ERROR);
            }

        }else if(userTakeBal.getDeviceType().equals(DeviceTypeEnum.DT_WORK_WECHAT.getKey())){//企业微信用户
            WxworkUser wxworkUser = wxworkUserMapper.selectById(userTakeBal.getUserId(), userTakeBal.getMerId());
            if (wxworkUser == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该企业微信用户不存在");
            }

            //计算用户余额并修改
            Double oldBalance = wxworkUser.getBalance();
            //修改余额
            newBalance = Math.add(oldBalance, userTakeBal.getTakeBal());
            newIntegral = wxworkUser.getIntegral();
            wxworkUser.setBalance(newBalance);
            wxworkUser.setUpdateTime(now);
            int j = wxworkUserMapper.updateBalance(wxworkUser);
            if (j != 1) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.NET_ERROR);
            }
        }else if(userTakeBal.getDeviceType().equals(DeviceTypeEnum.WX_PUB.getKey())) {//公众号用户
            WxpubUser wxpubUser = wxpubUserMapper.selectById(userTakeBal.getUserId(), userTakeBal.getMerId());
            if (wxpubUser == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该公众号用户不存在");
            }

            //计算用户余额并修改
            Double oldBalance = wxpubUser.getBalance();
            //修改余额
            newBalance = Math.add(oldBalance, userTakeBal.getTakeBal());
            newIntegral = wxpubUser.getIntegral();
            wxpubUser.setBalance(newBalance);
            wxpubUser.setUpdateTime(now);
            int j = wxpubUserMapper.updateBalance(wxpubUser);
            if (j != 1) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.NET_ERROR);
            }
        } else if (userTakeBal.getDeviceType().equals(DeviceTypeEnum.APP.getKey())) {//APP用户
            AppUser appUser = appUserMapper.selectById(userTakeBal.getUserId(), userTakeBal.getMerId());
            if (appUser == null) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该APP用户不存在");
            }

            //计算用户余额并修改
            Double oldBalance = appUser.getBalance();
            //修改余额
            newBalance = Math.add(oldBalance, userTakeBal.getTakeBal());
            newIntegral = appUser.getIntegral();
            appUser.setBalance(newBalance);
            appUser.setUpdateTime(now);
            int j = appUserMapper.updateBalance(appUser);
            if (j != 1) {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.NET_ERROR);
            }
        } else {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "目前还未支持该类型用户");
        }

        //增加账号入账明细
        UserAccDetail wechatUserAccDetail = new UserAccDetail();
        wechatUserAccDetail.setId(IdWorker.getId());
        wechatUserAccDetail.setMerId(userTakeBal.getMerId());
        wechatUserAccDetail.setUserId(userTakeBal.getUserId());
        wechatUserAccDetail.setDeviceUniqueId(userTakeBal.getDeviceUniqueId());
        wechatUserAccDetail.setDeviceType(userTakeBal.getDeviceType());
        wechatUserAccDetail.setChangeInte(0);
        wechatUserAccDetail.setChangeBal(userTakeBal.getTakeBal());
        wechatUserAccDetail.setNewBal(newBalance);
        wechatUserAccDetail.setNewInte(newIntegral);
        wechatUserAccDetail.setType(AccDetailTypeEnum.TAKE_BALANCE_REBACK.getValue());
        wechatUserAccDetail.setTradeno(userTakeBal.getTradeno());
        wechatUserAccDetail.setRemark(null);
        wechatUserAccDetail.setCreateTime(now);
        wechatUserAccDetail.setUpdateTime(now);
        int insert = userAccDetailMapper.insert(wechatUserAccDetail);
        if(insert!=1){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "增加账号明细失败");
        }
    }


    /**
     * 订单追回返利发送消息
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param user
     * @param baseOrderVo
     * @return null
     */
    private void sendMsgForRebateRefound(User user, BaseOrderVo baseOrderVo){
        //如果提现记录的机器人不存在，则取会员默认客户端机器人
        Device device = deviceService.findDeviceInfoByDeviceUniqueId(user.getDeviceUniqueId(), user.getDeviceType(), user.getMerId());
        if(device != null){
            ConfigPlan configPlan = configPlanMapper.selectById(device.getConfigId(), device.getMerId());
            if(configPlan != null){
                //发送提现审核成功文本消息
                SysPlugin sysPlugin = sysPluginMapper.selectById(configPlan.getTbId(), configPlan.getMerId());
                if(sysPlugin != null){
                    //发送提现审核成功文本消息
                    JSONObject jsonObject = JSONObject.parseObject(sysPlugin.getData());
                    if(jsonObject != null){
                        //订单追回返利订单回复买家（普通订单）
                        String message = jsonObject.getString("rebate_refound_reply_buyer");
                        //杀熟订单
                        if(Tools.getInteger(baseOrderVo.getNewUserOrder()).intValue() == 1){ //杀熟
                            message = jsonObject.getString("nuser_rebate_refound_reply_buyer");
                        }
                        if(StringUtils.isNotBlank(message)){
                            message = message.replace("[昵称]", Tools.getStr(user.getNickName()));
                            message = message.replace("[商品标题]", Tools.getStr(baseOrderVo.getTitle()));
                            message = message.replace("[订单编号]", Tools.getStr(baseOrderVo.getChildOrderNo()));
                            message = message.replace("[付款金额]", String.valueOf(Tools.getDouble(baseOrderVo.getPayment())));
                            message = message.replace("[返利金额]", String.valueOf(Tools.getDouble(baseOrderVo.getReUserBal())));
                            message = message.replace("[收回金额]", String.valueOf(Tools.getDouble(baseOrderVo.getReUserBal())));
                            message = message.replace("[收回积分]", String.valueOf(Tools.getInteger(baseOrderVo.getReUserInte())));
                            message = message.replace("[账户余额]", String.valueOf(Math.sub(Tools.getDouble(user.getBalance()), Tools.getDouble(baseOrderVo.getReUserBal()))));
                            String cmsGoodListUrl = cmsParamReplaceService.getCmsGoodListUrl(user.getMerId(), user.getId(), user.getDeviceUniqueId());
                            message = message.replace("[订单列表]", Tools.getStr(cmsGoodListUrl));

                            //发送MQ消息
                            MsgDto<NoticeMsgDto> msgDto = new MsgDto<>();
                            NoticeMsgDto  noticeMsgDto = new NoticeMsgDto();
                            msgDto.setContent(noticeMsgDto);
                            msgDto.setId(IdWorker.getId());
                            msgDto.setDeviceType(device.getRecvmsgType());
                            msgDto.setDeviceUniqueId(device.getId());
                            msgDto.setMerId(user.getMerId());
                            msgDto.setMsgType(MessageFuncEnum.SEND_CHAT_MESSAGE.getValue());
                            noticeMsgDto.setContent(message);
                            noticeMsgDto.setBizUserId(user.getBizUserId());
                            noticeMsgDto.setContentType(MessageTypeEnum.MT_TEXT.getValue());
                            noticeMsgDto.setGroupId(null);
                            noticeMsgDto.setNickName(user.getNickName());
                            noticeMsgDto.setMsgSource(1);
                            noticeMsgDto.setDelay(0);
                            noticeMsgDto.setMsgBizType(KefuSendMsgEnum.UNSOLICITEDMSG.getKey());
                            noticeMsgPushProducerService.sendMessage(msgDto);
                            log.info("发送订单追回返利回复语消息，para={}", JSONObject.toJSONString(msgDto));
                        }
                    }
                }
            }
        }
    }

}
